<?php

/**
 * @category   Ac
 * @package    Application_Model
 * @copyright  Orient Network Ltd
 * @license    Closed
 * @author     Olivier Bregeras
 */
class Model_User extends Ac_Model
{

    const TYPE = 1;
    
    const PERSONAL      = 1; //binary 001
    const AGENT         = 2; //binary 010
    const COMPANY_ADMIN = 6; //binary 110

    
    const STATUS_ACTIVE  = 1;
    const STATUS_BANNED  = 2;
    const STATUS_DELETED = 3;
    
    const ROLE_ADMIN = 1;

    protected static  $_collection = 'user';
	//conngroup for user and company models
   	protected static $_connectionGroup = 'accounts';
	//db for user and company
	protected static $_db = SHARED_ACCOUNTS_ENV;
    /**
     *
     * @var array define the requirements for this model
     */
    protected static $_requirements = array(
     //   'em'  => array('Required', 'Validator:EmailAddress'), //Email
    );

    protected static $_transcript = array(
        '_id' => '_id',
        'un'  => 'username',
        'nm'  => 'name',
        'em'  => 'email',
    	'emd' => 'emailed',
        'pw'  => 'password',
        'ti'  => 'twitterid',
        'fi'  => 'facebookid',
        'tis'  => 'twitter_token',
        'fis'  => 'facebook_token',
        'pp'  => 'profile_picture',
        'ph'  => 'phone',
        'cid' => 'company_id',
        'li'  => 'license_id',
        'sa'  => 'status',
        'c_dt'=> 'created_at',
        'p_dt'=> 'posted_at',
        'la'  => 'language',
        'ta'  => 'type_account',
        'nl'  => 'newsletter',
        'vf'  => 'verified',
        'se'  => 'services',
        'au'  => 'about_us',
        'csg' => 'campaign_samsung_galaxy',
        'csfb' => 'campaign_samsung_fb_name',
        'csn' => 'campaign_samsung_name',
        'caid' => 'campaign_id', //mongoId in the campaign collection
        'rl'  => 'role',
        'nsm' => 'no_street_map',
        'nv'  => 'number_views',
        'nsme' => 'no_send_message',
        'nu' => 'need_upgrade',
        'cli' => 'count_likes',
        'cfe' => 'count_followers',
        'cfi' => 'count_following',
		'ag' => 'agent_num',
		'cn' => 'contact_name',
		'ct' => 'contact_tel',
		'cm' => 'contact_msn',
		'l_t' => 'last_login_time'
    );

    private $_behavior;

    public function __construct($data = array(), $config = array())
	{
        $config['db'] = SHARED_ACCOUNTS_ENV;
        $config['collection'] = 'user';
        parent::__construct($data, $config);
        $this->_behavior = new Ac_User_Behavior_Regular();
    }

    public function setBehavior(Ac_User_Behavior_Interface $behavior)
    {
        $this->_behavior = $behavior;
    }

    public function getBehavior()
    {
        return $this->_behavior;
    }

    /**
     * Login a user if the user/password match.
     * @param array $user_info contains all info for the user
     */
    public function login($user_info = array()) {
        return $this->_behavior->login($this, $user_info);
    }


    /**
     * Login a user if the user/password match.
     * @param array $user_info contains all info for the user
     */
    public function register($user_info = array()) {
        return $this->_behavior->register($this, $user_info);
    }

    /**
     *
     * @param array $informations can contain an indefinite number of informations
     * @param boolean $force_login when the user is created for him to login
     */
    public function createUser(array $informations, $force_login = true) {

    }

    public function __toString() {
        if (!empty($this->username)) {
            return $this->username;
        }
        return '';
    }

    public function __call($name, $arguments)
    {
        if($name == 'history') {
            return Model_History::getList();
        } elseif($name == 'followers') {
            $limit = empty($arguments['limit']) ? 10 : $arguments['limit'];
            $list   = Model_Follow::getFollowers($this->_id)->limit($limit);
            return $list;            
        } else {
            return parent::_call($name, $arguments);
        }
    }

    public function __isset($name) {
        $val = self::__get($name);
        return!empty($val) ? true : parent::__isset($name);
    }
    

    public function __get($name)
    {
        if ($name == 'type') {
            //return parent::__get('title_'.Zend_Registry::get('current_language'));
            return empty($this->type_account) ? self::PERSONAL : $this->type_account;
        } elseif ($name == 'name') {
            return $this->username;
        } elseif($name == 'created_at') {
            $get = parent::__get('c_dt');
            if (!empty($get)) {
                if (is_object($get)) {
                    return $get->sec;
                } else {
                    return strtotime($get);
                }
            }
        } elseif($name == 'company') {
            return Model_Company::find($this->cid);
        } else {
            return parent::__get($name);
        }
    }

    public static function getNewPassword()
    {
        $length = 8;
        srand((double)microtime()*1000000);

        $vowels = array("a", "e", "i", "o", "u");
        $cons = array("b", "c", "d", "g", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", "u", "v", "w", "tr",
        "cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr", "sl", "cl");

        $num_vowels = count($vowels);
        $num_cons = count($cons);
        $password = '';
        for($i = 0; $i < $length; $i++){
            $password .= $cons[rand(0, $num_cons - 1)] . $vowels[rand(0, $num_vowels - 1)];
        }

        return rand(0, 9) . substr($password, 0, $length) . rand(0, 9);
    }

    public static function generatePassword($pw)
    {
        return md5($pw);
    }

    public static function generateUsername($str)
    {
        if ($arr = explode('@', $str)) { //email
            $name = preg_replace('#[^0-9a-zA-Z]#', '', $arr[0]);
            $name .= rand(0, 1000);
            //TODO::check in db the name doesn exists (we would not be very lucky)
        }
        return $name;
    }

    public function isProfileComplete()
    {
        if (empty($this->email)) {
            return false;
        }
        if (empty($this->username)) {
            return false;
        }
        /*
        if (empty($this->phone)) {
            return false;
        }
         *
         */
        return true;
    }

    public function url($full_url = false, $params = array())
    {
        
        $view = Zend_Registry::get('Zend_View');
        if (!empty($this->cid)) {
            return ($full_url ? 'http://'.$_SERVER['SERVER_NAME'].'/':'') . $view->geturl('display-company', 'user', array('company' => $this->company), 'company1', $params);
        } else {
            return ($full_url ? 'http://'.$_SERVER['SERVER_NAME'].'/':'') . $view->geturl('display', 'user', array('user' => $this), 'user1', $params);
        }
    }
    public function getPublishedAds()
    {
        $result = Model_Listing::all(array('us' => $this->_id, 'status' => Model_Listing::STATUS_PUBLISHED));
        return $result;
    }
    
    /**
     * We use Map/Reduce do to calculation on the number of views
     * @return int
     */
    public function getNoViews()
    {
        /*
        $map    = new MongoCode('function() { emit(this.user_id, this.nv); }');
        $reduce = new MongoCode('function(k, vals) { '.
            'var sum = 0;'.
            'for (var i in vals) {'.
                'sum += vals[i];'.
            '}'.
            'return sum; }');

        $sales = self::getMongoDb()->command(array(
            'mapreduce' => 'listing',
            'map'       => $map,
            'reduce'    => $reduce,
            'query'     => array('us' => $this->_id, 'sa' => Model_Listing::STATUS_PUBLISHED)));

        $views = self::getMongoDb()->selectCollection($sales['result'])->findOne();
        return $views['value'];
         * */
        return $this->number_views;
    }
    public function getNoShares()
    {
        return (5);
    }
    public function getNoResponses()
    {
        return (6);
    }

    public function getSolrDocument()
    {
        $document = new Apache_Solr_Document();
        $document->id = (string) $this->_id; //or something else suitably unique
        $document->type_obj = self::TYPE;
        $document->type_obj_s = 'Model_User';
        //$document->status   = (empty($this->status) || $this->status == self::STATUS_ACTIVE)? self::STATUS_ACTIVE : self::STATUS_BANNED;
        $document->status     = (empty($this->status) || $this->status == self::STATUS_ACTIVE)? self::STATUS_ACTIVE : (($this->status == self::STATUS_BANNED)?self::STATUS_BANNED : self::STATUS_DELETED);

        $document->username     = $this->username;
        $document->url          = $this->url();
        //$document->name     = $this->name;
        
        $document->email        = $this->email;
        
        //$document->has_twitter  = empty($this->twitter_id) ? 1: 0;
        $document->type_account    = empty($this->company_id) ? self::PERSONAL : self::COMPANY_ADMIN;
        if (is_object($this->created_at)) {
            $dt = $this->created_at->sec;
            
        } else {
            $dt = $this->created_at;
        }
        /*
        echo $this->c_dt;
        echo $this->created_at;
        var_dump($dt);
        echo gmdate('Y-m-d\TH:i:s\Z', $dt);
        exit;
        */
        //var_dump($this->created_at, $this->c_dt, gmdate ('Y-m-d\TH:i:s\Z', $this->created_at));exit;
        $document->created_at = gmdate('Y-m-d\TH:i:s\Z', $dt);
        if (!empty($this->updated_at)) {
            $document->updated_at = gmdate ('Y-m-d\TH:i:s\Z', $this->updated_at);
        }
        if (!empty($this->posted_at)) {
            $document->posted_at = gmdate ('Y-m-d\TH:i:s\Z', $this->posted_at);
        }
        
        return $document;
    }

    protected function preSaveAfterExport($exportData)
    {
        if (empty($this->c_dt)) {
            $this->c_dt = new MongoDate(time());
        }
        //$this->u_dt = new MongoDate(time());
    }

    public function postSave()
    {
        if (Zend_Registry::isRegistered('Zend_View')) { //to be sure getsorldocument can be executed
            $doc = $this->getSolrDocument();
            $client = Ac_Search::getClient();
            $client->addDocument($doc);
            //$client->commit();
            Zend_Registry::set('do_commit', 1);// any commit is now done at the end of the page loading            
        }

        //if the saved user if the same as the loggedin user also update loggedin user
		if (Zend_Registry::isRegistered('loggedin_user')) {
            $loggedin_user = Zend_Registry::get('loggedin_user');
            if ((string)$this->_id === (string)$loggedin_user->_id) {
                Zend_Registry::set('loggedin_user', $this);
                //var_dump($this->export(), Zend_Registry::get('loggedin_user')->export());exit;                
                $auth    = Zend_Auth::getInstance();
                if ($auth->hasIdentity()) {
                    $auth->getStorage()->write($this);
                    $cnt = $auth->getStorage()->read();
                }
            }
        }
        
        $cache = Zend_Registry::get('cache');
        $current_language = Zend_Registry::get('current_language');
        $key = 'header_' . (string)$this->_id .'__'.(!empty($current_language) ? $current_language : '');
        //echo $key.'----------------2';
        $cache->remove($key);
    }

    public static function cleanupUsername($username)
    {
        return strtolower(preg_replace('#[^a-zA-Z0-9]#ui', '-', $username));
    }

    /*
     * NOT USED ANYMORE
     */
    private function getSql()
    {
        $fields = $values = array();
        foreach($this->export() as $k => $v) {
            if(in_array($k, array('un', 'pw', 'em', 'c_dt', 'p_dt'))) {
                if($k == 'un') {//username
                    $values['username'] = $v;
                } elseif($k == 'c_dt') {//createdate
                    $values['CreateDate'] = date('Y-m-d h:i:s', $v->sec);
                } elseif($k == 'p_dt') {//postdate
                    $values['PostDate'] = date('Y-m-d h:i:s', $v->sec);
                } elseif($k == 'em') {//category
                    $values['email'] = $v;
                } elseif($k == 'pw') {//password
                    $values['password'] = $v;
                }
            }
        }
        //var_dump($values);
        if (!empty($this->id)) {
            $str = 'UPDATE user SET';
            $to_add = '';
            foreach($values as $k => $v) {
                $str .= $to_add . ' '. $k.'=\''.addslashes($v).'\'';
                $to_add = ' ,';
            }
            $str .= ' WHERE userid = '. $this->id.' LIMIT 1';
        } elseif (!empty($this->email)) {
            $str     = 'SELECT * FROM user WHERE email = \''.addslahes($this->email).'\'';
            $client  = Ac_Util::getMysqlConnection();
            if ($row = $client->query($str)) {
                $this->id = $row['UserID'];
            }
            $str = 'UPDATE user SET';
            $to_add = '';
            foreach($values as $k => $v) {
                $str .= $to_add . ' '. $k.'=\''.addslashes($v).'\'';
                $to_add = ' ,';
            }
            $str .= ' WHERE userid = '. $this->id.' LIMIT 1';
                
        }
        if (empty($this->id)) {
    
            $str = 'INSERT INTO user ';
            $str1 = 'UserStatusID, ';
            $str2 = '1, ';
            $to_add = '';
            foreach($values as $k => $v) {
                $str1 .= $to_add . $k;
                $str2 .= $to_add . '\''.addslashes($v).'\'';
                $to_add = ' ,';
            }
            $str .='('.$str1.') VALUES ('.$str2.') ';
        }
        return $str;
    }
	
	public function deleteUser()
	{
		$this->status = Model_User::STATUS_DELETED;
		$this->forceSave();
	}
	
    public function forceSave()
    {
        $this->save();
        $this->postSave();
        $client = Ac_Search::getClient();
        $client->commit();
    }

    public function exportRest($include_session = false)
    {

        if (!empty($this->status) && $this->status != self::STATUS_ACTIVE) {
            throw new Ac_Exception_MissingInformation('User does not exists');
        }

        $view = Zend_Registry::get('Zend_View');
        $res = array(
            '_id' => (string)$this->_id,
            'username' => (string) !empty($this->username) ? $this->username : '',
            'status' => (string) !empty($this->status) ? (string) $this->status : '4',
            'user_url_tc' => $this->url(false, 'tc'),
            //'user_photo' =>  !empty($this->profile_picture) ?  Ac_Util::getImageBaseUrl('/images/photo/original/'.$this->profile_picture) : '',
            'about_us' => (string) $this->about_us,
            'created_at' => (string) $this->c_dt->sec,

        );

        if (!empty($this->profile_picture)) {
            $res['photo'] = Ac_Util::getImageBaseUrl('/images/photo/original/'.$this->profile_picture);
            $res['thumbnail'] = $view->thumbnail()->scale($this->profile_picture, 150, 150);
        } else {
            $res['photo'] = Ac_Util::getImageBaseUrl('/images/no-photo.png');
            $res['thumbnail'] = $view->thumbnail()->scale('', 150, 150);
        }

        if(!empty($this->cid)) {
            $res['company_id'] = (string) $this->cid;
        }

        if ($include_session) {
            $res['session_id'] = (string) $this->sess;
        }
        return $res;
    }
    

}


